/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import java.util.ArrayList;
import java.util.Locale;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import pojo.Property;

/**
 *
 * @author HoangLiem
 */
public class ExecIdXML {

    /*
     *  Hàm này lấy các ID của 1 table
     */
    public static ArrayList<Property> getIdsOfTable(Document doc, String tableName) {
        ArrayList<Property> Properties = new ArrayList<Property>();
        try {
            doc.getDocumentElement().normalize();
            NodeList nl = doc.getElementsByTagName("id");
            Node node = null;
            Element pt = null;
            for (int i = 0; i < nl.getLength(); i++) {
                node = nl.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    pt = (Element) node;
                    Property temp = new Property();
                    Element pr = (Element) pt.getParentNode();
                    if (pr.getAttribute("name").equalsIgnoreCase(tableName)) {
                        temp.setName(pt.getAttribute("name").toString());
                        temp.setLength(Integer.parseInt(pt.getAttribute("length")));
                        temp.setType(pt.getAttribute("type").toString());
                        temp.setNotnull(ExecTableXML.convertElementNotnull(pt));
                        temp.setUnique(ExecTableXML.convertElementUnique(pt));
                        Properties.add(temp);
                    }
                }
            }
            if (Properties.isEmpty()) {
                Properties = null;
            }
        } catch (Exception e) {
            Properties = null;
            e.printStackTrace();
        }
        return Properties;
    }

    public static ArrayList<Property> getIdsOfTable(String databaseName, String tableName) {
        databaseName = databaseName.toLowerCase().trim();
        tableName = tableName.toLowerCase().trim();
        try {
            Document doc = ExecXML.getDocument(databaseName + ".xml");
            return getIdsOfTable(doc, tableName);
        } catch (Exception ex) {
            return null;
        }
    }
    /*
     *  Hàm này lấy 1 ID của 1 table theo thuộc tính name của id
     */

    public static Property getIdOfTable(Document doc, String tableName, String nameID) {
        Property id = new Property();
        try {
            doc.getDocumentElement().normalize();
            NodeList nl = doc.getElementsByTagName("id");
            Node node = null;
            Element pt = null;
            if (nl.getLength() > 0) {
                for (int i = 0; i < nl.getLength(); i++) {
                    node = nl.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        pt = (Element) node;

                        Element pr = (Element) pt.getParentNode();
                        if (pr.getAttribute("name").equalsIgnoreCase(tableName) && pt.getAttribute("name").equalsIgnoreCase(nameID)) {
                            id.setName(pt.getAttribute("name"));
                            id.setLength(Integer.parseInt(pt.getAttribute("length")));
                            id.setType(pt.getAttribute("type"));
                            id.setNotnull(ExecTableXML.convertElementNotnull(pt));
                            id.setUnique(ExecTableXML.convertElementUnique(pt));
                        }
                    }
                }
            }
        } catch (Exception e) {
            id = null;
            e.printStackTrace();
        }
        return id;
    }

    public static Property getIdOfTable(String databaseName, String tableName, String nameID) {
        databaseName = databaseName.toLowerCase().trim();
        tableName = tableName.toLowerCase().trim();
        nameID = nameID.toLowerCase().trim();
        try {
            Document doc = ExecXML.getDocument(databaseName + ".xml");
            return getIdOfTable(doc, tableName, nameID);
        } catch (Exception ex) {
            return null;
        }
    }
    /*
     * Ham nay kiem tra 1 ten id co ton tai trong cac the id không
     */

    public static boolean isExistedID(Document doc, String tableName, String idName) {
        try {
            //ArrayList<String> tableNames = getNamesOfTable(doc);
            ArrayList<Property> ids = getIdsOfTable(doc, tableName);
            ArrayList<String> proName = new ArrayList<String>();
            if (ids != null && !ids.isEmpty()) {
                for (int i = 0; i < ids.size(); i++) {
                    proName.add(ids.get(i).getName().toString().toLowerCase());
                }
            } else {
                return false;
            }
            return ExecXML.isExistedString(proName, idName.toLowerCase());
        } catch (Exception ex) {
            return true;
        }
    }
    /*
     * Add 1 ID vào table trong file.
     */

    public static boolean addIDToTable(Document doc, String nameTable, Property pt) {
        boolean result = true;
        if (ExecTableXML.isExistedFieldName(doc, nameTable, pt.getName())) {
            return result = false;
        }
        try {
            doc.getDocumentElement().normalize();
            NodeList nl = doc.getElementsByTagName("table");
            Node node = null;
            Element table = null;
            for (int i = 0; i < nl.getLength(); i++) {
                node = nl.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    table = (Element) node;
                    if (table.getAttribute("name").equalsIgnoreCase(nameTable)) {
                        if (table.getAttribute("name").equalsIgnoreCase(nameTable)) {
                            Element property = doc.createElement("id");
                            property.setAttribute("name", pt.getName().toLowerCase());
                            property.setAttribute("type", pt.getType().toLowerCase());
                            property.setAttribute("length", Integer.toString(pt.getLength()).toLowerCase());
                            property.setAttribute("unique", ExecTableXML.convertUnique(pt).toLowerCase());
                            property.setAttribute("notnull", ExecTableXML.convertNotnull(pt).toLowerCase());

                            Node proNode = ExecXML.getFirstNodeByNodeName(doc, nameTable, "property");
                            Node fkNode = ExecXML.getFirstNodeByNodeName(doc, nameTable, "foreignkey");
                            Node rowNode = ExecXML.getFirstNodeByNodeName(doc, nameTable, "row");
                            if (proNode != null) {
                                table.insertBefore(property, proNode);
                                table.insertBefore(doc.createTextNode("\n\t\t"), proNode);
                            } else {
                                if (fkNode != null) {
                                    table.insertBefore(property, fkNode);
                                    table.insertBefore(doc.createTextNode("\n\t\t"), fkNode);
                                } else {
                                    if (rowNode != null) {
                                        table.insertBefore(property, rowNode);
                                        table.insertBefore(doc.createTextNode("\n\t\t"), rowNode);
                                    } else {
                                        if (table.hasChildNodes()) {
                                            table.appendChild(doc.createTextNode("\t"));
                                        } else {
                                            table.appendChild(doc.createTextNode("\n\t\t"));
                                        }
                                        table.appendChild(property);
                                        table.appendChild(doc.createTextNode("\n\t"));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            String xPath = "database/table[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" + nameTable.toLowerCase() + "']/row";
            NodeList nodeList = (NodeList) ExecXML.execXpathReturnNodeList(doc, xPath);
            if (nodeList.getLength() == 0) {
                ExecXML.saveXmlFile(doc, ExecTableXML.getNameDatabase(doc) + ".xml");
            } else {
                return result = false;
            }
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        return result;
    }

    /*
     * hàm này xóa 1 id của table, nếu có fk nào có thuộc tính tableref là table chứa id thì ko cho xóa
     */
    public static boolean deleteID(Document doc, String tableName, String idName) {
        boolean result = true;
        if (!ExecIdXML.isExistedID(doc, tableName, idName)) {
            return result = false;
        }
        //Lấy hết tất cả các fk trong database chứa table chứa id này
        doc.getDocumentElement().normalize();
        NodeList nl = doc.getElementsByTagName("foreignkey");
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            Element e = (Element) node;
            // Nếu có fk nào có thuộc tính tableref chứa tableName thì ko cho xóa table.
            if (e.getAttribute("tableref").equalsIgnoreCase(tableName)) {
                return result = false;
            }
        }

        try {
            doc.getDocumentElement().normalize();
            //Lấy id có thuộc tính name = idName trong table có thuộc tính name = tableName            
            String xPath = "database/table[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" + tableName.toLowerCase() + "']/id[@name='" + idName + "']";
            Node id = (Node) ExecXML.execXpath(doc, xPath, "node");
            // Tiến hành xóa id
            id.getParentNode().removeChild(id);
            // Xóa thuộc tính này ở các row để cập nhật
            ExecRowXML.deleteAttributeOfRow(doc, tableName, idName);

            ExecXML.saveXmlFile(doc, ExecTableXML.getNameDatabase(doc) + ".xml");
        } catch (Exception ex) {
            result = false;
        }
        return result;
    }
}
